home *** CD-ROM | disk | FTP | other *** search
/ Delphi Developer's Kit 1996 / Delphi Developer's Kit 1996.iso / power / wfc007.000 / src / csquigl.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-22  |  9.5 KB  |  413 lines

  1. #include <wfc.h>
  2. #pragma hdrstop
  3.  
  4. /*
  5. ** Author: Samuel R. Blackburn
  6. ** CI$: 76300,326
  7. ** Internet: sammy@sed.csc.com
  8. **
  9. ** You can use it any way you like.
  10. */
  11.  
  12. #if defined( _DEBUG )
  13. #undef THIS_FILE
  14. static char BASED_CODE THIS_FILE[] = __FILE__;
  15. #endif
  16.  
  17. /*
  18. ** The data that will be squiggle-ized...
  19. */
  20.  
  21. IMPLEMENT_SERIAL( CSquiggleData, CObject, 1 )
  22.  
  23. CSquiggleData::CSquiggleData()
  24. {
  25.    m_Initialize();
  26. }
  27.  
  28. CSquiggleData::~CSquiggleData()
  29. {
  30.    m_Initialize();
  31. }
  32.  
  33. void CSquiggleData::Copy( const CSquiggleData *source_p )
  34. {
  35.    if ( source_p == (CSquiggleData *) NULL )
  36.    {
  37.       m_Initialize();
  38.       return;
  39.    }
  40.  
  41.    Start        = source_p->Start;
  42.    Stop         = source_p->Stop;
  43.    Time         = source_p->Time;
  44.    MinimumValue = source_p->MinimumValue;
  45.    MaximumValue = source_p->MaximumValue;
  46.  
  47.    /*
  48.    ** MFC doesn't provide an equals (assignment) operator for their CWordArray class. Odd, they provide one for
  49.    ** CString... Anyway, we've got to write a bunch of code that should have already been written
  50.    */
  51.  
  52.    Data.RemoveAll();
  53.    
  54.    int number_of_elements = source_p->Data.GetSize();
  55.    int index              = 0;
  56.    
  57.    Data.SetSize( number_of_elements );
  58.  
  59.    while( index < number_of_elements )
  60.    {
  61.       Data.Add( source_p->Data.GetAt( index ) );
  62.       index++;
  63.    }
  64. }
  65.  
  66. void CSquiggleData::Empty( void )
  67. {
  68.    m_Initialize();
  69. }
  70.  
  71. void CSquiggleData::m_Initialize( void )
  72. {
  73.    Start.Empty();
  74.    Stop.Empty();
  75.    Time = CTime( 0 );
  76.    MinimumValue = 0;
  77.    MaximumValue = 0;
  78.    Data.RemoveAll();
  79. }
  80.  
  81. void CSquiggleData::Serialize( CArchive& archive )
  82. {
  83.    CObject::Serialize( archive );
  84.  
  85.    if ( archive.IsStoring() )
  86.    {
  87.       archive << Start;
  88.       archive << Stop;
  89.       archive << Time;
  90.       archive << MinimumValue;
  91.       archive << MaximumValue;
  92.    }
  93.    else
  94.    {
  95.       archive >> Start;
  96.       archive >> Stop;
  97.       archive >> Time;
  98.       archive >> MinimumValue;
  99.       archive >> MaximumValue;
  100.    }
  101.  
  102.    Data.Serialize( archive );
  103. }
  104.  
  105. WORD CSquiggleData::ValidRange( void )
  106. {
  107.    if ( MinimumValue > MaximumValue )
  108.    {
  109.       WORD temp_word = MaximumValue;
  110.       MaximumValue = MinimumValue;
  111.       MinimumValue = temp_word;
  112.    }
  113.  
  114.    return( (WORD) ( MaximumValue - MinimumValue ) );
  115. }
  116.  
  117. /*
  118. ** The Squiggle that you see on the screen
  119. */
  120.  
  121. IMPLEMENT_SERIAL( CSquiggle, CRectangle, 1 )
  122.  
  123. CSquiggle::CSquiggle()
  124. {
  125.    m_Automatically_Delete = FALSE;
  126.    m_PointArray           = (POINT *) NULL;
  127.    m_Initialize();
  128. }
  129.  
  130. CSquiggle::CSquiggle( DWORD height, DWORD width, const CPoint& location, COLORREF fill_color, COLORREF line_color )
  131.           :CRectangle( height, width, location, fill_color, line_color )
  132. {
  133.    m_Automatically_Delete = FALSE;
  134.    m_PointArray           = (POINT *) NULL;
  135.    m_Initialize();
  136. }
  137.  
  138. CSquiggle::~CSquiggle()
  139. {
  140.    if ( m_PointArray != (POINT *) NULL )
  141.    {
  142.       delete [] m_PointArray;
  143.       m_PointArray = (POINT *) NULL;
  144.    }
  145.  
  146.    if ( m_Automatically_Delete == TRUE )
  147.    {
  148.       delete m_Squiggle_Data_p;
  149.    }
  150.  
  151.    m_Initialize();
  152. }
  153.  
  154. void CSquiggle::Copy( const CSquiggle *source_p )
  155. {
  156.    m_Initialize();
  157.  
  158.    CSquiggleData *data_p = new CSquiggleData;
  159.  
  160.    data_p->Copy( source_p->m_Squiggle_Data_p );
  161.  
  162.    SetSquiggleData( data_p, TRUE );
  163.  
  164.    CRectangle::Copy( source_p );
  165. }
  166.  
  167. void CSquiggle::Draw( CDC& device_context )
  168. {
  169.    if ( m_Squiggle_Data_p == (CSquiggleData *) NULL )
  170.    {
  171.       return;
  172.    }
  173.  
  174.    CBitmap bitmap;
  175.  
  176.    CDC temporary_device_context;
  177.  
  178.    CBrush brush( m_FillColor );
  179.  
  180.    DWORD width  = GetWidth();
  181.    DWORD height = GetHeight();
  182.  
  183.    BOOL result = bitmap.CreateCompatibleBitmap( &device_context, (int) width, (int) height );
  184.  
  185.    if ( result == 0 )
  186.    {
  187.       return;
  188.    }
  189.  
  190.    result = temporary_device_context.CreateCompatibleDC( &device_context );
  191.  
  192.    if ( result == 0 )
  193.    {
  194.       return;
  195.    }
  196.  
  197.    CBitmap *original_bitmap = temporary_device_context.SelectObject( &bitmap );
  198.  
  199.    temporary_device_context.FillRect( CRect( 0, 0, (int) width, (int) height ), &brush );
  200.  
  201.    /*
  202.    ** Draw the grid if we need to
  203.    */
  204.  
  205.    if ( m_NumberOfXGridLines > 0 || m_NumberOfYGridLines > 0 )
  206.    {
  207.       CPen grid_line_pen( (int) m_GridLineType, 1, m_GridLineColor );
  208.  
  209.       CPen *original_pen = temporary_device_context.SelectObject( &grid_line_pen );
  210.  
  211.       /*
  212.       ** Now turn the background color into the same color as our FillRect to prevent
  213.       ** dotted pens from being color-white-color...
  214.       */
  215.  
  216.       COLORREF original_background_color = temporary_device_context.SetBkColor( m_FillColor );
  217.  
  218.       int index = 0;
  219.  
  220.       for( index = 1; index < m_NumberOfXGridLines; index++ )
  221.       {
  222.          temporary_device_context.MoveTo( (int) ( index * width / m_NumberOfXGridLines ), 0            );
  223.          temporary_device_context.LineTo( (int) ( index * width / m_NumberOfXGridLines ), (int) height );
  224.       }
  225.  
  226.       for( index = 1; index < m_NumberOfYGridLines; index++ )
  227.       {
  228.          temporary_device_context.MoveTo( 0,           (int) ( index * height / m_NumberOfYGridLines ) );
  229.          temporary_device_context.LineTo( (int) width, (int) ( index * height / m_NumberOfYGridLines ) );
  230.       }
  231.  
  232.       temporary_device_context.SetBkColor( original_background_color );
  233.       temporary_device_context.SelectObject( original_pen );
  234.       grid_line_pen.DeleteObject();
  235.    }
  236.  
  237.    CPen line_pen( PS_SOLID, (int) m_LineThickness, m_LineColor );
  238.  
  239.    CPen *original_pen = temporary_device_context.SelectObject( &line_pen );
  240.  
  241.    temporary_device_context.Polyline( (LPPOINT) m_PointArray, m_NumberOfPoints );
  242.  
  243.    /*
  244.    ** Copy to the screen
  245.    */
  246.  
  247.    device_context.BitBlt( m_Location.x, m_Location.y, (int) width, (int) height, &temporary_device_context, 0, 0, SRCCOPY );
  248.  
  249.    /*
  250.    ** Clean up
  251.    */
  252.  
  253.    temporary_device_context.SelectObject( original_pen    );
  254.    temporary_device_context.SelectObject( original_bitmap );
  255.    line_pen.DeleteObject();
  256.    bitmap.DeleteObject();
  257. }
  258.  
  259. void CSquiggle::Empty( void )
  260. {
  261.    m_Initialize();
  262. }
  263.  
  264. DWORD CSquiggle::GetLineThickness( void ) const
  265. {
  266.    return( m_LineThickness );
  267. }
  268.  
  269. void CSquiggle::m_Initialize( void )
  270. {
  271.    m_Squiggle_Data_p     = (CSquiggleData *) NULL;
  272.    m_PointArray          = (POINT *) NULL;
  273.    m_NumberOfPoints      = 0;
  274.    m_NumberOfXGridLines  = 0;
  275.    m_NumberOfYGridLines  = 0;
  276.    m_GridLineColor       = DARK_GREEN;
  277.    m_LineThickness       = 1;
  278.    m_GridLineType        = PS_DOT;
  279. }
  280.  
  281. void CSquiggle::Serialize( CArchive& archive )
  282. {
  283.    CRectangle::Serialize( archive );
  284.  
  285.    if ( archive.IsStoring() )
  286.    {
  287.       archive << m_NumberOfXGridLines;
  288.       archive << m_NumberOfYGridLines;
  289.       archive << m_GridLineColor;
  290.       archive << m_LineThickness;
  291.       archive << m_GridLineType;
  292.  
  293.       DWORD do_we_have_data = 0;
  294.  
  295.       if ( m_Squiggle_Data_p != (CSquiggleData *) NULL )
  296.       {
  297.          do_we_have_data = 1;
  298.       }
  299.  
  300.       archive << do_we_have_data;
  301.  
  302.       if ( do_we_have_data == 1 )
  303.       {
  304.          m_Squiggle_Data_p->Serialize( archive );
  305.       }
  306.    }
  307.    else
  308.    {
  309.       archive >> m_NumberOfXGridLines;
  310.       archive >> m_NumberOfYGridLines;
  311.       archive >> m_GridLineColor;
  312.       archive >> m_LineThickness;
  313.       archive >> m_GridLineType;
  314.  
  315.       DWORD is_there_data = 0;
  316.  
  317.       archive >> is_there_data;
  318.  
  319.       if ( is_there_data == 1 )
  320.       {
  321.          CSquiggleData *data_p = new CSquiggleData;
  322.  
  323.          data_p->Serialize( archive );
  324.  
  325.          SetSquiggleData( data_p, TRUE );
  326.       }
  327.    }
  328. }
  329.  
  330. void CSquiggle::SetGridLineColor( COLORREF grid_line_color )
  331. {
  332.    m_GridLineColor = grid_line_color;
  333. }
  334.  
  335. void CSquiggle::SetGridLineType( DWORD type )
  336. {
  337.    m_GridLineType = type;
  338. }
  339.  
  340. void CSquiggle::SetLineThickness( DWORD thickness )
  341. {
  342.    m_LineThickness = thickness;
  343. }
  344.  
  345. void CSquiggle::SetNumberOfGridLines( WORD number_of_x_lines, WORD number_of_y_lines )
  346. {
  347.    m_NumberOfXGridLines = number_of_x_lines;
  348.    m_NumberOfYGridLines = number_of_y_lines;
  349. }
  350.  
  351. void CSquiggle::SetSquiggleData( CSquiggleData *source_p, BOOL auto_delete )
  352. {
  353.    if ( m_PointArray != (POINT *) NULL )
  354.    {
  355.       delete [] m_PointArray;
  356.       m_PointArray = (POINT *) NULL;
  357.    }
  358.  
  359.    m_NumberOfPoints = 0;
  360.  
  361.    if ( m_Automatically_Delete == TRUE )
  362.    {
  363.       delete m_Squiggle_Data_p;
  364.       m_Squiggle_Data_p = (CSquiggleData *) NULL;
  365.       m_Automatically_Delete = FALSE;
  366.    }
  367.  
  368.    if ( source_p != (CSquiggleData *) NULL )
  369.    {
  370.       m_Squiggle_Data_p      = source_p;
  371.       m_Automatically_Delete = auto_delete;
  372.  
  373.       m_NumberOfPoints = source_p->Data.GetSize();
  374.  
  375.       m_PointArray = new POINT[ m_NumberOfPoints ];
  376.  
  377.       if ( m_PointArray == (POINT *) NULL )
  378.       {
  379.          /*
  380.          ** Out of Memory
  381.          */
  382.  
  383.          m_NumberOfPoints = 0;
  384.          return;
  385.       }
  386.  
  387.       int number_of_data_points = m_NumberOfPoints;
  388.  
  389.       if ( number_of_data_points == 0 )
  390.       {
  391.          number_of_data_points = 1;
  392.       }
  393.  
  394.       int valid_range = m_Squiggle_Data_p->ValidRange();
  395.  
  396.       if ( valid_range == 0 )
  397.       {
  398.          valid_range = 1;
  399.       }
  400.  
  401.       double x_ratio = (double) GetWidth()  / (double) number_of_data_points;
  402.       double y_ratio = (double) GetHeight() / (double) valid_range;
  403.  
  404.       int origin_y = (int) ( (double) m_Squiggle_Data_p->MaximumValue * y_ratio );
  405.  
  406.       for ( int index = 0; index < m_NumberOfPoints; index++ )
  407.       {
  408.          m_PointArray[ index ].x = (int) ( (double) index * x_ratio );
  409.          m_PointArray[ index ].y = origin_y - (int) ( (double) m_Squiggle_Data_p->Data.GetAt( index ) * y_ratio );
  410.       }
  411.    }
  412. }
  413.